SpringCloud学习(5)

您所在的位置:网站首页 zuul 读音 SpringCloud学习(5)

SpringCloud学习(5)

2024-06-13 15:40| 来源: 网络整理| 查看: 265

目录 前言一、Zuul快速入门二、Zuul常用配置2.1 监控界面与忽略服务配置2.2 灰度发布 三、Zuul过滤器3.1 Zuul过滤器快速入门3.2 PreFilter实现token校验3.3 Zuul的降级

前言

上一篇:Hystrix详解 Zuul(网关)在SpringCloud中非常重要,非常重要,Zuul网关的作用类似Nginx的作用,Nginx可以做请求转发,Nginx来管理服务的ip地址,客户端只要访问Nginx的端口即可,具体转发访问哪个服务又Nginx转发,Zuul也有这种功能,并Zuul能认证与授权,如果Zuul认为一个请求有权限,才会进行转发给对应服务。除此之外,如果服务有迭代更改,也只需要改Zuul配置,客户端无需改动,还可限流,优点多多,使用起来却很简单。 优点: 1、请求转发,客户端无需再维护大量服务端口 2、认证和授权操作 3、可做限流与安全 4、项目迭代,导致项目拆分或更改,不用动客户端,只要修改Zuul配置 在这里插入图片描述

一、Zuul快速入门

创建一个新module,maven项目,命名为zuul_01 常见几步:导入依赖、配置yml、配置启动类+启动Zuul注解、最后测试

注意:zuul是也是通过在Eureka中注册从而访问其他服务

第一步:导入依赖

org.springframework.cloud spring-cloud-starter-netflix-eureka-client org.springframework.cloud spring-cloud-starter-netflix-zuul org.springframework.boot spring-boot-starter-web

第二步:配置application.yml

# 指定往哪个EurekaServer服务中注册 eureka: client: serviceUrl: defaultZone: http://root:root@localhost:8761/eureka/,http://root:root@localhost:8762/eureka/ # 指定服务名称,为了区分创建的服务 spring: application: name: zuul server: port: 8001

第三步:启动类,注解开@EnableEurekaClient和@EnableZuulProxy,因为Zuul要在Eureka中注册

@SpringBootApplication @EnableEurekaClient @EnableZuulProxy public class ZuulApplication { public static void main(String[] args) { SpringApplication.run(ZuulApplication.class,args); } }

启动ZuulApplication,输入localhost:8761看看已经启动的服务,这里你要把我前几篇案例也看了,拿代码运行,都是有关联的 在这里插入图片描述 通过Zuul的端口8001,输入服务名+接口就可以访问到对应的服务,过程就是Zuul->Customer->Pay调用 在这里插入图片描述

二、Zuul常用配置 2.1 监控界面与忽略服务配置

Zuul监控界面没有Hystrix好看,比较简单,效果如下,配置好的服务可以到Zuul这里看看是否生效,如地址含/customer/**就会到customer服务找,遇到遇到/eureka/**就会到eureka服务中找,和nginx相似 在这里插入图片描述 那我们怎么配置呢?老生常谈的几步

第一步:导入依赖 新增

org.springframework.boot spring-boot-starter-actuator

第二步:配置yml 新增

# zuul的监控界面,开发时配置为*,上线无需配置 management: endpoints: web: exposure: include: "*"

然后重启,输入http://localhost:8001/actuator/routes即可在这里插入图片描述

如果想移出某个服务呢?application.yml增加如下配置 在这里插入图片描述 重启程序,刷新界面,会发现eureka服务直接移除了,customer服务还在,但是无法访问它 在这里插入图片描述

#zuul配置 zuul: ignored-services: eureka #基于服务名忽略,如要忽略全部服务用* ignored-patterns: /**/search/** #监控界面还是看得到,但是无法访问,会404

自定义配置方式:如果你想把这个下面路径换个其他名字,可以用自定义配置 在这里插入图片描述

#zuul配置 zuul: ignored-services: eureka #基于服务名忽略,如要忽略全部服务用* ignored-patterns: /**/pay/** #监控界面还是看得到,但是无法访问,会404 routes: payClient: /pay/** #服务名:新路径 customer: /user/**

这样就创建了新的可以访问的路径,当然旧的也可以使用,两种等价 在这里插入图片描述 不想用旧的,可以忽略,比如我们这里写ignored-services: "*"试试,重启,刷新,以前的访问方式就忽略了,所以这样就可以按自己所需改访问名字 在这里插入图片描述 如下输入http://localhost:8001/user/customer/2得到下面结果,以前是http://localhost:8001/customer/customer/2,现在改了下名字而已 在这里插入图片描述 我们暂时不用这个忽略,先注释 在这里插入图片描述

2.2 灰度发布

什么是灰度发布? 灰度发布就是在版本迭代过程,如app发布了一个新版本,更新的用户用心的接口调用功能,而老用户还是用老接口调用功能,那么采用灰度发布,就能平衡好新老版本,怎么做?两步即可

第一步:Zuul启动类增加@Bean代码块,Zuul是通过版本的方式,新版本Zuul会让对应服务用新版接口,老版本用老的

@Bean public PatternServiceRouteMapper serviceRouteMapper(){ return new PatternServiceRouteMapper( "(?^.+)-(?v.+$)", "${version}/${name}" ); }

第二步:准备一个服务,弄出两个版本

先做如下操作 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

将新旧Customer都重启,ZuulApplication也重启,改动的都重启,然后查看Zuul的监控界面,那么新的就会以/v1/customer出现,如果再加customer就会变成/v2/customer,zuul都会自动进行

在这里插入图片描述

如果你没有得到v1和v2,只有一个v1,没有v2则证明你的有问题,一般是注册的问题,我就碰到了,最后我思考认为应该让所以服务都注册,然后Eureka中有全部服务,Zuul再注册,它就能获取到所有服务了

在这里插入图片描述 启动要按照这个顺序启动就没问题 在这里插入图片描述 于是就能根据不同版本进行访问 在这里插入图片描述

三、Zuul过滤器

过滤器是Zuul的核心组件,我们先看看它的执行流程,如下图 在这里插入图片描述 客户端请求发送到Zuul服务上,首先通过PreFilter过滤器链,这个过滤器可以做限流、权限验证等操作,如果请求无误,则正常放行,请求再次转发给RoutingFilter,RouteFilter会将请求转发到指定服务得到响应结果,再将结果传递回RoutingFilter,RouteFilter再将结果传递给PostFilter过滤器链,最终再将响应信息交给客户端。

提供四种过滤器

3.1 Zuul过滤器快速入门

在zuul模块创建两个自定义过滤器类,继承ZuulFilter,重写四个方法 在这里插入图片描述

@Component public class TestZuulFilter extends ZuulFilter { @Override public String filterType() { return FilterConstants.PRE_TYPE;//设置过滤器类型,前置过滤器 } @Override public int filterOrder() { return FilterConstants.PRE_DECORATION_FILTER_ORDER - 1; //设置过滤器执行顺序,数字越小会先执行,这里比前置小,就会在前置过滤器之前执行 } @Override public boolean shouldFilter() { return true; //是否开启当前过滤器 } @Override public Object run() throws ZuulException { System.out.println("prefix过滤器已经执行"); return null; } } import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.exception.ZuulException; import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants; import org.springframework.stereotype.Component; @Component public class TestZuulFilter2 extends ZuulFilter { @Override public String filterType() { return FilterConstants.PRE_TYPE;//设置过滤器类型,前置过滤器 } @Override public int filterOrder() { return FilterConstants.PRE_DECORATION_FILTER_ORDER + 1; //设置过滤器执行顺序,数字越小会先执行,这里比前置小,就会在前置过滤器之前执行 } @Override public boolean shouldFilter() { return true; //是否开启当前过滤器 } @Override public Object run() throws ZuulException { System.out.println("prefix过滤器222已经执行"); return null; } }

重启ZuulApplication,然后随机访问一个地址,比如这个http://localhost:8001/v1/customer/version,控制台就会打印下面结果 在这里插入图片描述

FilterConstants.PRE_DECORATION_FILTER_ORDER - 1的TestZuulFilter先执行,因为越小的数字会先执行,源码中默认为5

3.2 PreFilter实现token校验

创建一个AuthenticFilter,继承ZuulFilter

import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.RequestContext; import com.netflix.zuul.exception.ZuulException; import org.apache.http.HttpStatus; import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants; import javax.servlet.http.HttpServletRequest; @Component //一定记得加component交给SPring管理 public class AuthenticFilter extends ZuulFilter { @Override public String filterType() { return FilterConstants.PRE_TYPE; } @Override public int filterOrder() { return FilterConstants.PRE_DECORATION_FILTER_ORDER - 2;//最前进行校验 } @Override public boolean shouldFilter() { return true; } @Override public Object run() throws ZuulException { //1、获取request对象 RequestContext currentContext = RequestContext.getCurrentContext(); HttpServletRequest request = currentContext.getRequest(); //2、获取token参数 String token = request.getParameter("token"); //3、对比token if(token == null || !("123".equals(token))){//假设token查到为123 //4、token校验失败,直接响应数据 currentContext.setSendZuulResponse(false);//不响应 currentContext.setResponseStatusCode(HttpStatus.SC_UNAUTHORIZED);//401 } return null; } }

上面的token实际通过Redis查找、也可以是其他查出token,注意自己定义的Filter要用@Component,交给Spring管理

重启ZuulApplication,浏览器刷新,返回401不可访问HttpStatus.SC_UNAUTHORIZED就是401状态码,表示未授权,校验失败 在这里插入图片描述 token正确则放行 在这里插入图片描述

3.3 Zuul的降级

Zuul默认会包括Hystrix依赖,所以不用再导入关于降级的Hystrix依赖,本质是Zuul整合Hystrix实现降级,返回托底数据 在这里插入图片描述 创建ZuulFallBack实现降级 在这里插入图片描述

import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.client.ClientHttpResponse; import org.springframework.stereotype.Component; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; @Component public class ZuulFallBack implements FallbackProvider { @Override public String getRoute() { return "*"; //指定全部出现问题的服务都走这个降级方法 } @Override public ClientHttpResponse fallbackResponse(String route, Throwable cause) {//route表示服务名 System.out.println("降级的服务:"+route); cause.printStackTrace();//问题打印 return new ClientHttpResponse() { @Override public HttpStatus getStatusCode() throws IOException { return HttpStatus.INTERNAL_SERVER_ERROR; //INTERNAL_SERVER_ERROR(500, "Internal Server Error"), } @Override public int getRawStatusCode() throws IOException { return HttpStatus.INTERNAL_SERVER_ERROR.value(); //500状态码 } @Override public String getStatusText() throws IOException { //指定错误信息 return HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase(); } @Override public void close() { } @Override public InputStream getBody() throws IOException { String msg = "当前服务:"+ route + ",出现问题"; return new ByteArrayInputStream(msg.getBytes()); } @Override public HttpHeaders getHeaders() { //指定响应头信息 HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); return headers; } }; } }

阅读上面代码,有注释 新增睡眠 在这里插入图片描述 重启Customer有关服务(两个),再重启ZuulApplication服务,输入地址http://localhost:8001/v2/customer/version?token=123 在这里插入图片描述 控制台会打印原因,读超时Read timed out,因为睡眠了 在这里插入图片描述

代码: 链接:https://pan.baidu.com/s/1U3ebAqfIS-s_7gqqyuOSGQ 提取码:233x



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3